import os

from flask import Flask, jsonify, request, send_from_directory, abort
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt, get_jwt_identity
from sqlalchemy import create_engine
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import sessionmaker
from datetime import datetime, timedelta

from werkzeug.utils import secure_filename

from Models import User, Worker, Document, Turn, Schedule, array_to_worker_time, load_schedules_stu, \
    is_second_week_of_month

app = Flask(__name__)

# 设置会话密钥
app.secret_key = '22861334'

# 配置JWT密钥
app.config['JWT_SECRET_KEY'] = '123456789'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(days=1)  # 设置访问令牌的过期时间为 1 天
app.config['JWT_REFRESH_TOKEN_EXPIRES'] = timedelta(days=1)  # 设置刷新令牌的过期时间为 1 天
# 初始化JWTManager
jwt = JWTManager(app)
# 连接数据库
engine = create_engine('sqlite:///database.db')

# 创建数据库表对象
User.__table__.create(bind=engine,checkfirst=True)
Worker.__table__.create(bind=engine,checkfirst=True)
Document.__table__.create(bind=engine,checkfirst=True)
Turn.__table__.create(bind=engine,checkfirst=True)
Schedule.__table__.create(bind=engine,checkfirst=True)
Session = sessionmaker(bind=engine)

# session = Session()
# new_user = User(username='test',password='111',name='test user')
# session.add(new_user)
# session.commit()
# session.close()


@app.route('/',methods=['GET'])
def index():
    print("hello")
    return jsonify({'msg': 'Hello'})

# 登录
@app.route('/login',methods=['POST'])
def login():
    # 假设这里从请求中解析用户名和密码
    username = request.json.get('username', None)
    password = request.json.get('password', None)

    # 这里应该是与你的数据库或用户认证系统交互的代码

    if not username or not password:
        return jsonify({"code":1,"msg": "用户名或密码错误"}), 400

    # 新建会话
    session = Session()
    # 查询结果
    user = session.query(User).filter_by(username=username).first()
    # 判断密码
    if not user or user.password != password:
        return jsonify({"code": 1, "msg": "用户名或密码错误"}), 401
    if user.power == 0:
        worker = session.query(Worker).filter_by(stu_id=username).first()
        if not worker:
            return jsonify({'code':1,'msg':'你现在还不是工作人员，无法登陆'}), 400
        if worker.status == 0:
            return jsonify({'code':1,'msg':'你现在已经离职，无法登陆'}), 400

    power = user.power
    if power == 0:
        stu_id = username
    else:
        stu_id = None

    # 创建访问令牌
    access_token = create_access_token(identity=username,additional_claims={"power":user.power})

    data = {
        "name":user.name,
        "token":access_token,
        "power":user.power,
        "stu_id":stu_id
    }
    response_data = {
        "code":0,
        "msg":"OK",
        "data":data
    }
    return jsonify(response_data), 200

@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():

    claims = get_jwt()
    print(claims)
    power = claims.get('power')
    print(power)

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    return jsonify({"code": 0, "msg": "访问成功", "data": "这里是受保护的数据"}), 200

# 获取所有管理员
@app.route('/manage',methods=['GET'])
@jwt_required()
def all_manager():

    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    session = Session()
    try:
        managers = session.query(User).filter_by(power=1).all()

        if not managers:
            return jsonify({'code':1,'msg':'没有管理员'}),400

        data = []
        for manager in managers:
            data.append({
                'name':manager.name,
                'id':manager.username
            })

        response_data = {
            'code':0,
            'msg':'查询所有管理员成功',
            'data':data
        }

        return jsonify(response_data),200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 修改自己的密码
@app.route('/editpw',methods=['PUT'])
@jwt_required()
def alter_password():

    identity = get_jwt_identity()

    session = Session()
    try:
        user = session.query(User).filter_by(username=identity).first()

        if not user:
            return jsonify({'code':1,'msg':f'没有找到该用户，用户名：{identity}'}),400

        password = request.json.get('password')
        if not password:
            return jsonify({'code':1,'msg':f'没有输入密码'}),400

        new_password = request.json.get('newpassword')
        if not new_password:
            return jsonify({'code':1,'msg':f'没有输入新密码'}),400

        confirm_new_password = request.json.get('repassword')
        if not confirm_new_password:
            return jsonify({'code':1,'msg':f'请重新输入新密码'}),400

        if password != user.password:
            return jsonify({'code':1,'msg':f'原密码不正确，用户名：{identity}'}),400

        if new_password == user.password:
            return jsonify({'code':1,'msg':'新密码不可与原密码一致'}),400

        if new_password != confirm_new_password:
            return jsonify({'code':1,'msg':'两次输入的新密码不一致'}),400

        user.password = new_password
        session.commit()

        return jsonify({'code':0,'msg':'密码修改成功'}),200


    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 管理员重置维修人密码
@app.route('/person/resetpw',methods=['PUT'])
@jwt_required()
def set_password():

    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    session = Session()
    try:
        stu_id = request.json.get('stu_id',None)
        if not stu_id:
            session.query(User).filter_by(power=0).update({User.password:'123456'}, synchronize_session=False)

            session.commit()
            return jsonify({"code": 0, "msg": "修改成功,已将全部维修人的密码设置为默认值：123456"}), 200

        user = session.query(User).filter_by(username=stu_id).first()
        if not user:
            return jsonify({"code": 1, "msg": f"找不到该学号的维修人,学号{stu_id}"}), 400

        user.password = '123456'
        session.commit()

        return jsonify({"code": 0, "msg": "修改成功"}), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()


# 新增维修人
@app.route('/person',methods=['POST'])
@jwt_required()
def add_new_worker():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403


    # 接收数据
    data = request.json
    # 获取姓名，学号
    name = data.get('name')
    stu_id = data.get('stu_id')

    # 检查必需的字段是否存在
    if not name or not stu_id:
        return jsonify({"code":1,'msg': '缺少姓名或学号'}), 400

    # 新建会话
    session = Session()

    try:

        # 创建对象
        new_user = User(username=stu_id,name=name)
        new_worker = Worker(stu_id=stu_id, name=name)
        session.add(new_user)
        session.add(new_worker)
        session.commit()

        # 创建返回对象
        response_data = {
            "code":0,
            "msg":"OK"
        }
        return jsonify(response_data), 200  # 返回成功状态

    except IntegrityError:
        session.rollback()  # 回滚会话以处理数据完整性错误
        return jsonify({"code":1,'msg': 'This student ID already exists'}), 409  # 冲突错误

    except Exception as e:
        session.rollback()  # 处理其他异常
        return jsonify({"code":1,'msg': str(e)}), 500  # 服务器错误

    finally:
        session.close()  # 确保会话关闭

# 查看所有维修人
@app.route('/person',methods=['GET'])
@jwt_required()
def get_all_worker():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    # 接收数据
    data = request.args
    # 获取页码，页长，姓名，学号
    page_num = data.get('pagenum',1)  #默认页码是1
    page_size = data.get('pagesize',10)  #默认页长是10
    name = data.get('name',None)  #可选的过滤条件1
    stu_id = data.get('stu_id',None) #可选的过滤条件
    status = data.get('status',None)

    #转换成数字
    if page_num.isdigit():  # 检查是否为有效的数字字符串
        page_num = int(page_num)
    else:
        page_num = 1  # 如果不是有效的数字，设置为默认值

    if page_size.isdigit():  # 检查是否为有效的数字字符串
        page_size = int(page_size)
    else:
        page_size = 10  # 如果不是有效的数字，设置为默认值

    # 新建会话
    session = Session()

    # 总查询
    query = session.query(Worker)

    if name:
        query = query.filter(Worker.name.ilike(f'%{name}%'))  #模糊匹配
    if stu_id:
        query = query.filter(Worker.stu_id.ilike(f'%{stu_id}%'))
    if status:
        query = query.filter(Worker.status.ilike(f'%{status}%'))

    # 总Worker数
    total = query.count()
    # 指定页码，页长
    workers = query.offset((page_num - 1)*page_size).limit(page_size).all()

    # 关闭会话
    session.close()

    record = []
    for worker in workers:
        record.append({"stu_id":worker.stu_id,
                       "name":worker.name,
                       "status":worker.status})

    data = {
        "record":record,
        'total':total
    }

    response_data = {
        "data":data,
        "code":0,
        "msg":"OK"
    }

    return jsonify(response_data),200

# 修改维修人在职状态
@app.route('/person',methods=['PUT'])
@jwt_required()
def alter_status():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    stu_id = request.json.get("stu_id",None)
    status = int(request.json.get("status",None))

    # 检查参数是否有效
    if not stu_id :
        return jsonify({"code":1,"msg": "学号错误"}), 400
    if status is None:
        return jsonify({"code":1,"msg": "状态错误"}), 400

    # 新建会话
    session = Session()

    try:
        # 查询
        worker = session.query(Worker).filter_by(stu_id=stu_id).first()

        if not worker:
            return jsonify({"code":1,"msg": "找不到该学号对应的维修人员"}), 404

        worker.status = status

        session.commit()

        # 返回成功消息
        return jsonify({"code":0,"msg": "在职状态更新成功"}), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 删除维修人
@app.route('/person',methods=['DELETE'])
@jwt_required()
def del_worker():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403


    # 获取学号
    stu_id = request.args.get("stu_id",None)

    # 检查参数是否有效
    if not stu_id:
        return jsonify({"code":1,"msg": "需要学号"}), 400

    session = Session()
    try:
        # 直接删除stu_id为指定值的行
        worker = session.query(Worker).filter_by(stu_id=stu_id).first()
        user = session.query(User).filter_by(username=stu_id).first()


        if not worker:
            return jsonify({"code": 1, "msg": "找不到对应的维修人员"}), 404
        if not user:
            return jsonify({"code": 1, "msg": "找不到对应的用户"}), 404
        if worker.status == 1:
            return jsonify({"code": 1, "msg": "该人员还没离职"}), 400
        if user.power == 1:
            return jsonify({"code": 1, "msg": "管理员无法删除"}), 400

        session.delete(worker)
        session.delete(user)

        # 提交更改
        session.commit()

        response_data = {
            "code":0,
            "msg":"删除成功"
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 查找维修人员的值班记录
@app.route('/person/record',methods=['GET'])
@jwt_required()
def search_worker_record():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403


    session = Session()
    try:
        last_public_schedule = session.query(Schedule).filter_by(status=2).first()
        stu_id = request.args.get('stu_id',None)
        if last_public_schedule is None:
            return jsonify({'code':1,'msg':'无排班记录'})

        week = request.args.get('week',None)
        if not week:
            week = last_public_schedule.week

        if not stu_id:
            return jsonify({"code": 1, "msg": "找不到对应的维修人员"}), 404

        record = []
        # 定义一个包含所有要检查的时间段和相应字段名的列表
        periods = [
            ('s1', ['1', '2', '3', '4']),
            ('s2', ['1', '2', '3', '4']),
            ('s3',  ['1', '2', '3', '4','5','6']),
            ('s4',  ['1', '2', '3', '4','5','6']),
            ('s5', ['1', '2', '3', '4'])
        ]


        schedules = session.query(Schedule).filter_by(week=week)
        for schedule in schedules:
            # 遍历所有时间段和它们的子时间段
            for period_prefix, sub_periods in periods:
                # 对每个子时间段，检查对应的Schedule字段
                for sub_period in sub_periods:
                    field_name = f"{period_prefix}_{sub_period}"
                    # 使用getattr获取字段值，然后检查它是否等于stu_id
                    if getattr(schedule, field_name) == str(stu_id):
                        record.append(1)
                        break
                    elif sub_period == '6' and getattr(schedule, field_name) != str(stu_id):
                        record.append(0)
                    elif period_prefix not in ('s3','s4') and sub_period == '4' and getattr(schedule, field_name) != str(stu_id):
                        record.append(0)


        response_data = {
            "code":0,
            "msg":"查询成功",
            "data":{
                "week":week,
                "record":record
            }
        }

        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()


# 查找自己本月值班时长
@app.route('/stu/grade',methods=['GET'])
@jwt_required()
def search_grade():


    stu_id = request.args.get("stu_id",None)

    # 检查参数是否有效
    if not stu_id:
        return jsonify({"code":1,"msg": "需要学号"}), 400

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')
    identity = claims.get('sub')

    if power < 1 and identity != stu_id:  # 假设权限等级大于0的用户或者id对应才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    # 新建会话
    session = Session()
    try:
        # 查询
        worker = session.query(Worker).filter_by(stu_id=stu_id).first()
        if not worker:
            return jsonify({"code":1,"msg": "找不到维修人员"}), 404
        grade = worker.grade

        response_data = {
            "data":{
                "grade":grade,
            },
            "code":0,
            "msg":"查询成功"
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 上传个人值班时间
@app.route('/stu/time',methods=['POST'])
@jwt_required()
def upload_work_time():
    time = request.json.get('time',None)
    stu_id = request.json.get('stu_id',None)

    # 检查参数是否有效
    if not stu_id:
        return jsonify({"code":1,"msg": "需要正确学号"}), 400
    if not time:
        return jsonify({"code":1,"msg": "需要正确值班时间"}), 400

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')
    identity = get_jwt_identity()

    if power < 1 and identity != stu_id:
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    session = Session()
    try:
        # 查询
        worker = session.query(Worker).filter_by(stu_id=stu_id).first()
        if not worker:
            return jsonify({"code":1,"msg": "找不到维修人员"}), 404
        worker.work_time = array_to_worker_time(time)
        session.commit()

        response_data = {
            "code":0,
            "msg":"值班信息上传成功"
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()


# 获取个人值班时间段
@app.route('/stu/time',methods=['GET'])
@jwt_required()
def get_work_time():
    stu_id = request.args.get('stu_id',None)
    # 检查参数是否有效
    if not stu_id:
        return jsonify({"code":1,"msg": "需要正确学号"}), 400

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')
    identity = get_jwt_identity()

    if power < 1 and identity != stu_id:
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    session = Session()
    try:
        # 查询
        worker = session.query(Worker).filter_by(stu_id=stu_id).first()
        if not worker:
            return jsonify({"code":1,"msg": "找不到维修人员"}), 404

        record = worker.get_worker_time_array()

        response_data = {
            "code":0,
            "msg":"查询值班时间段成功",
            "data":{
                "record":record
            }
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 查看排班表
@app.route('/stu/duty',methods=['GET'])
@jwt_required()
def search_schedule():

    # 初始化
    record = {
        "mon":{
            "one":[],
            "two":[],
            "three":[],
            "four":[],
            "five":[]
        },
        "tue":{
            "one":[],
            "two":[],
            "three":[],
            "four":[],
            "five":[]
        },
        "wed":{
            "one":[],
            "two":[],
            "three":[],
            "four":[],
            "five":[]
        },
        "thu":{
            "one":[],
            "two":[],
            "three":[],
            "four":[],
            "five":[]
        },
        "fri":{
            "one":[],
            "two":[],
            "three":[],
            "four":[],
            "five":[]
        },
        "sat":{
            "one":[],
            "two":[],
            "three":[],
            "four":[],
            "five":[]
        },
        "sun":{
            "one":[],
            "two":[],
            "three":[],
            "four":[],
            "five":[]
        }
    }

    week = request.args.get('week',None)

    session = Session()
    try:
        # 默认最新发布的周
        last_public_schedule = session.query(Schedule).filter_by(status=2).first()
        if not last_public_schedule:
            response_data = {
                "code":0,
                "msg":"查询排班表成功",
                "data":{
                    "week":0,
                    "record":record
                }
            }
            # 返回消息
            return jsonify(response_data), 200
        if not week:
            week = last_public_schedule.week

        schedules = session.query(Schedule).filter_by(week=week)
        if not schedules:
            return jsonify({"code":1,"msg": "找不到排班信息"}), 404



        # 装入学号
        record = load_schedules_stu(schedules,record,session)

        response_data = {
            "code":0,
            "msg":"查询排班表成功",
            "data":{
                "week":int(week),
                "record":record
            }
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()



# 显示所有维修人本月时长
@app.route('/person/time',methods=['GET'])
@jwt_required()
def search_all_grade():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403


    # 获取页码，页长
    page_num = request.args.get('pagenum',1)  #默认页码是1
    page_size = request.args.get('pagesize',10)  #默认页长是10

    if page_num.isdigit():  # 检查是否为有效的数字字符串
        page_num = int(page_num)
    else:
        page_num = 1  # 如果不是有效的数字，设置为默认值

    if page_size.isdigit():  # 检查是否为有效的数字字符串
        page_size = int(page_size)
    else:
        page_size = 10  # 如果不是有效的数字，设置为默认值

    # 新建会话
    session = Session()

    # 总查询
    query = session.query(Worker).filter_by(status=1)

    # 总Worker数
    total = query.count()
    # 指定页码，页长
    workers = query.offset((page_num - 1)*page_size).limit(page_size).all()

    # 关闭会话
    session.close()

    record = []
    for worker in workers:
        record.append({"stu_id":worker.stu_id,
                       "name":worker.name,
                       "grade":worker.grade})

    data = {
        "record":record,
        'total':total
    }

    response_data = {
        "data":data,
        "code":0,
        "msg":"查询成功"
    }

    return jsonify(response_data),200

# 确认清零本月时长
@app.route('/person/confirmtime',methods=['POST'])
@jwt_required()
def confirm_grade():

    # 创建一个新的session
    session = Session()
    try:
        # 更新Worker表中所有记录的grade为0
        session.query(Worker).update({Worker.grade:0}, synchronize_session=False)

        # 提交更改
        session.commit()

        return jsonify({'code':0,'msg': '成功确认本月时长，时长已清零'}), 200

    except Exception as e:
        # 如果发生异常，回滚事务并返回错误信息
        if session:
            session.rollback()
        return jsonify({'code':1,'msg': str(e)}), 500

    finally:
        # 关闭session
        if session:
            session.close()

# @app.route('/test',methods=['GET'])
# def init_data():
#
#     session = Session()
#
#     try:
#         # 初始化数据
#         for i in range(1, 21):  # 1 到 20 周
#             for j in range(1, 8):  # 1 到 7 天
#                 schedule = Schedule(week=i, day=j)  # 每次循环都创建新的 Schedule 实例
#                 session.add(schedule)
#
#                 # 一次性提交所有更改
#         session.commit()
#
#     except Exception as e:
#         session.rollback()  # 如果发生错误，回滚更改
#         return jsonify({"error": str(e)}), 500
#
#     finally:
#         session.close()  # 确保会话被关闭
#
#     return jsonify({"OK": "OK"})

# 手动排班
# @app.route('/duty',methods=['PUT'])


# 获取当前最新发布的值班表
@app.route('/duty',methods=['GET'])
@jwt_required()
def get_schedule():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    week = request.args.get('week',None)

    session = Session()
    try:
        # 查询
        if not week:
            schedule = session.query(Schedule).filter_by(status=2).first()
            if not schedule:
                week = 1
            else:
                week = schedule.week

        schedules = session.query(Schedule).filter_by(week=week)


        status = session.query(Schedule).filter_by(week=week).first().status
        if not schedules:
            return jsonify({"code":1,"msg": "找不到该周目"}), 404

        # 初始化
        record = {
            "mon":{
                "one":[],
                "two":[],
                "three":[],
                "four":[],
                "five":[]
            },
            "tue":{
                "one":[],
                "two":[],
                "three":[],
                "four":[],
                "five":[]
            },
            "wed":{
                "one":[],
                "two":[],
                "three":[],
                "four":[],
                "five":[]
            },
            "thu":{
                "one":[],
                "two":[],
                "three":[],
                "four":[],
                "five":[]
            },
            "fri":{
                "one":[],
                "two":[],
                "three":[],
                "four":[],
                "five":[]
            },
            "sat":{
                "one":[],
                "two":[],
                "three":[],
                "four":[],
                "five":[]
            },
            "sun":{
                "one":[],
                "two":[],
                "three":[],
                "four":[],
                "five":[]
            }
        }

        # 装入学号
        record = load_schedules_stu(schedules,record,session)

        response_data = {
            "code":0,
            "msg":"查询排班表成功",
            "data":{
                "week":int(week),
                "status":int(status),
                "record":record
            }
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 自动排班
@app.route('/duty',methods=['POST'])
@jwt_required()
def auto_schedule():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    # 时间段
    periods = ["s1_1", "s1_2", "s1_3", "s1_4",
               "s2_1", "s2_2", "s2_3", "s2_4",
               "s3_1", "s3_2", "s3_3", "s3_4", "s3_5", "s3_6",
               "s4_1", "s4_2", "s4_3", "s4_4", "s4_5", "s4_6",
               "s5_1", "s5_2", "s5_3", "s5_4"]

    session = Session()

    try:
        week = session.query(Turn).first().week
        workers = session.query(Worker).filter_by(status=1).all()
        result = session.query(Schedule).filter_by(status=1).first()
        if result is None:
            return jsonify({'code':1,'msg':'没有可供排班的时间'}),400
        sorted_stu = sorted(workers,key=lambda workers: workers.grade)

        # 清空原有的排班
        old_schedules = session.query(Schedule).filter_by(status=1,week=week).all()
        for old_schedule in old_schedules:
            for period in periods:
                setattr(old_schedule,period,None)

        # 排班
        for stu in sorted_stu:
            n = 0
            for s in stu.work_time:
                if s == "1":
                    schedule = n%5+1
                    day = n//5+1
                    schedules = session.query(Schedule).filter_by(week=week,day=day,status=1).first()
                    if schedule in (3,4):
                        for i in range(1,7):
                            if getattr(schedules, "s" + str(schedule) + "_" + str(i)) is None:
                                setattr(schedules, "s" + str(schedule) + "_" + str(i),stu.stu_id)
                                break
                    else:
                        for i in range(1,5):
                            if getattr(schedules, "s" + str(schedule) + "_" + str(i)) is None:
                                setattr(schedules, "s" + str(schedule) + "_" + str(i),stu.stu_id)
                                break
                n += 1

        session.commit()
        response_data = {
            "code":0,
            "msg":"自动排班成功"
        }

        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        session.close()



# 手动修改排班
@app.route('/duty',methods=['PUT'])
@jwt_required()
def edit_schedule():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    week = request.json.get('week',None)
    day = request.json.get('day',None)
    schedule = request.json.get('schedule',None)
    record = request.json.get('record',None)

    if not week or not day or not schedule:
        return jsonify({'code':1,'msg':'需要正确参数'})
    if (len(record) > 6 and schedule in (3,4)) or (len(record) > 4 and schedule in (1,2,5)):
        return jsonify({'code':1,'msg':'超出正常人员'})

    session = Session()
    try:
        # 查询
        schedules = session.query(Schedule).filter_by(week=week,day=day).first()
        if not schedules:
            return jsonify({"code":1,"msg": "找不到该周目"}), 404

        # 清空原有排班信息
        if schedule in (3,4):
            for i in range(1,7):
                setattr(schedules,'s'+str(schedule)+'_'+str(i),None)
        else:
            for i in range(1,5):
                setattr(schedules,'s'+str(schedule)+'_'+str(i),None)

        i = 1
        for stu in record:
            setattr(schedules,'s'+str(schedule)+'_'+str(i),stu)
            i += 1

        session.commit()

        response_data = {
            "code":0,
            "msg":"修改排班表成功"
            }

        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 开始下一周
@app.route('/duty/nextweek',methods=['POST'])
@jwt_required()
def next_week():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    session = Session()
    try:
        # 查询
        public_schedule = session.query(Schedule).filter_by(status=2).first()
        if not public_schedule:
            return jsonify({"code":1,"msg": "开始下一周排班失败,有未发布的值班表"}), 404

        week = public_schedule.week
        result = session.query(Schedule).filter_by(week=week+1,status=0).update({Schedule.status:1},
                                                                          synchronize_session=False)
        if not result:
            return jsonify({"code":1,"msg": "开始下一周排班失败"}), 404

        session.commit()

        response_data = {
            "code":0,
            "msg":"新一周更改成功"
        }

        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        session.close()


# 新学期开始
@app.route('/duty/newterm',methods=['POST'])
@jwt_required()
def new_term_schedule():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    session = Session()
    try:
        # 查询
        schedules = session.query(Schedule).update({Schedule.status: 0,
                                                    Schedule.s1_1:None,
                                                    Schedule.s1_2:None,
                                                    Schedule.s1_3:None,
                                                    Schedule.s1_4:None,
                                                    Schedule.s2_1:None,
                                                    Schedule.s2_2:None,
                                                    Schedule.s2_3:None,
                                                    Schedule.s2_4:None,
                                                    Schedule.s3_1:None,
                                                    Schedule.s3_2:None,
                                                    Schedule.s3_3:None,
                                                    Schedule.s3_4:None,
                                                    Schedule.s3_5:None,
                                                    Schedule.s3_6:None,
                                                    Schedule.s4_1:None,
                                                    Schedule.s4_2:None,
                                                    Schedule.s4_3:None,
                                                    Schedule.s4_4:None,
                                                    Schedule.s4_5:None,
                                                    Schedule.s4_6:None,
                                                    Schedule.s5_1:None,
                                                    Schedule.s5_2:None,
                                                    Schedule.s5_3:None,
                                                    Schedule.s5_4:None}, synchronize_session=False)
        session.query(Schedule).update({Schedule.status:0}, synchronize_session=False)
        session.query(Schedule).filter_by(week=1).update({Schedule.status:1}, synchronize_session=False)
        week = session.query(Turn).update({Turn.week:1}, synchronize_session=False)
        session.query(Worker).update({Worker.grade:0}, synchronize_session=False)
        if not schedules or not week:
            return jsonify({"code":1,"msg": "修改失败"}), 404

        session.commit()

        response_data = {
            "code":0,
            "msg":"新学期更改成功"
        }

        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 使用上一个发布的排班
@app.route('/duty/continue',methods=['POST'])
@jwt_required()
def last_schedule():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    # 时间段
    periods = ["s1_1", "s1_2", "s1_3", "s1_4",
               "s2_1", "s2_2", "s2_3", "s2_4",
               "s3_1", "s3_2", "s3_3", "s3_4", "s3_5", "s3_6",
               "s4_1", "s4_2", "s4_3", "s4_4", "s4_5", "s4_6",
               "s5_1", "s5_2", "s5_3", "s5_4"]

    session = Session()
    try:
        # 查询
        last_week_schedule = session.query(Schedule).filter_by(status=2).first()
        if not last_week_schedule:
            return jsonify({"code":1,"msg": "当前已经是第一周"}), 400
        week = last_week_schedule.week
        last_schedules = session.query(Schedule).filter_by(week=week,status=2).all()
        schedules = session.query(Schedule).filter_by(week=week+1,status=1).all()
        if not last_schedules or not schedules:
            return jsonify({"code":1,"msg": "找不到周目"}), 404

        for old,new in zip(last_schedules,schedules):
            for period in periods:
                setattr(new,period,getattr(old,period))

        session.commit()

        response_data = {
            "code":0,
            "msg":"排班成功"
        }

        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        session.close()



# 发布排班表
@app.route('/duty/post',methods=['POST'])
@jwt_required()
def declare_schedule():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    # 时间段
    periods = ["s1_1", "s1_2", "s1_3", "s1_4",
               "s2_1", "s2_2", "s2_3", "s2_4",
               "s3_1", "s3_2", "s3_3", "s3_4", "s3_5", "s3_6",
               "s4_1", "s4_2", "s4_3", "s4_4", "s4_5", "s4_6",
                "s5_1", "s5_2", "s5_3", "s5_4"]

    now_date = datetime.now()

    session = Session()
    try:
        week = session.query(Turn).first().week  #获取当前周
        if week !=1:
            # 当前周排班表状态变为不可修改
            result = session.query(Schedule).filter_by(week=week-1,status=2).update({Schedule.status:3},
                                                                        synchronize_session=False)
            if not result:
                return jsonify({'code':1,'msg':'当前周已发布'}), 400

        # 获取当前周值班信息
        schedules = session.query(Schedule).filter_by(week=week).all()
        # 获取上周的值班信息
        last_schedules = session.query(Schedule).filter_by(week=week-1).all()
        # 更新最新可编辑的周
        session.query(Turn).update({Turn.week:week+1}, synchronize_session=False)
        # 获取在岗人员
        stus = session.query(Worker).filter_by(status=1).all()
        if is_second_week_of_month(now_date):
            # 每个月第二周清空值班时长
            session.query(Worker).update({Worker.grade:0}, synchronize_session=False)

        # 改变本周的值班表状态
        for schedule in schedules:
            if schedule.status == 0:
                return jsonify({'code':1,'msg':'当前周已发布'}), 400
            schedule.status = 2

        # 统计上周的工时
        if last_schedules is not None:
            for last_public_schedule in last_schedules:
                for stu in stus:
                    for period in periods:
                        if getattr(last_public_schedule,period) == str(stu.stu_id):
                            if period in ("s4_1", "s4_2", "s4_3", "s4_4", "s4_5", "s4_6"):
                                stu.grade += 1
                            else:
                                stu.grade += 2

        session.commit()
        response_data = {
            "code":0,
            "msg":"更新成功"
        }

        return jsonify(response_data),200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()


# 查看排班表格式
@app.route('/format',methods=['GET'])
@jwt_required()
def get_turn():

    session = Session()
    try:

        turn = session.query(Turn)
        record = []
        for i in turn:
            record.append({
                "index":i.id,
                "start":i.start,
                "end":i.end
            })

        response_data = {
            "code":0,
            "msg":"值班表信息获取成功",
            "data":{
                "record":record
            }
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 查询全部人上传的值班时间段
@app.route('/duty/time',methods=['GET'])
@jwt_required()
def get_time_schedule():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    day = request.args.get('day',None)
    schedule = request.args.get('schedule',None)

    if not day:
        return jsonify({'code':1,'msg':'需要正确参数'}),400
    if not schedule:
        return jsonify({'code':1,'msg':'需要正确参数'}),400

    day = int(day)
    schedule = int(schedule)
    num = (day-1)*5+schedule-1
    data = []

    session = Session()
    try:
        workers = session.query(Worker).filter_by(status=1).all()
        for worker in workers:
            if worker.work_time[num] == "1":
                data.append({
                    "stu_id":worker.stu_id,
                    "name":worker.name
                })

        response_data = {
            "code":0,
            "msg":"获取成功",
            "data":data
        }

        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 编辑排班表格式
@app.route('/duty/edit',methods=['PUT'])
@jwt_required()
def edit_turn():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    records = request.json.get('record',None)

    # 检查参数是否有效
    if not records:
        return jsonify({"code":1,"msg": "需要正确信息"}), 400

    session = Session()
    try:
        for record in records:
            # 查询
            turn = session.query(Turn).filter_by(id=record['index']).first()
            if not turn :
                return jsonify({"code": 1, "msg": f"找不到id为{record['index']}的排班信息"}), 404

            turn.start = record['start']
            turn.end = record['end']

        session.commit()

        response_data = {
            "code":0,
            "msg":"值班表信息编辑成功"
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()

# 获取某个时间段可以值班的人员列表
@app.route('/duty/person',methods=['GET'])
@jwt_required()
def get_schedule_stu():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:  # 假设只有权限等级大于0的用户才能访问
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    day = int(request.args.get('day',None))
    schedule = int(request.args.get('schedule',None))

    # 检查参数是否有效
    if not day:
        return jsonify({"code":1,"msg": "需要正确日期"}), 400
    if not schedule:
        return jsonify({"code":1,"msg": "需要正确班次"}), 400

    num = (day-1)*5+schedule-1
    data = []

    session = Session()
    try:
        workers = session.query(Worker).filter_by(status=1).all()
        for worker in workers:
            if worker.work_time[num] == "1":
                data.append({
                    "stu_id":worker.stu_id,
                    "name":worker.name
                })

        response_data = {
            "code":0,
            "msg":"获取成功",
            "data":data
        }

        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()




#  PDF 文件存储在服务器的 './Doc' 目录下
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'Doc')
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
MAX_CONTENT_LENGTH = 10 * 1024 * 1024  # 文件最大10MB

@app.route('/pdfs/show',methods=['GET'])
@jwt_required()
def download_file():

    file_id = request.args.get('id')  # 默认返回 None 如果没有找到 'id'

    if not file_id:
        abort(400, "Filename is required.")  # 如果没有提供 filename，则返回 400 错误

    session = Session()
    try:
        file = session.query(Document).filter_by(id=file_id).first()

        if not file:
            return jsonify({'code':1,'msg':'没找到文件'}),400

        filename = file.path

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()


    # print(f"UPLOAD_FOLDER: {UPLOAD_FOLDER}")  # 调试输出
    # print(f"Filename: {filename}")  # 调试输出
    file_path = os.path.join(UPLOAD_FOLDER, filename)

    if not os.path.exists(file_path):
        abort(404, f"File {filename} does not exist.")

    return send_from_directory(UPLOAD_FOLDER, filename)

# 获取全部文件
@app.route('/pdfs',methods=['GET'])
@jwt_required()
def search_all_files():

    page_num = request.args.get('pagenum',1)  #默认页码是1
    page_size = request.args.get('pagesize',10)  #默认页长是10
    title = request.args.get('filetitle',None)  #可选的过滤条件1
    contributor = request.args.get('contributor',None) #可选的过滤条件


    #转换成数字
    if page_num.isdigit():  # 检查是否为有效的数字字符串
        page_num = int(page_num)
    else:
        page_num = 1  # 如果不是有效的数字，设置为默认值

    if page_size.isdigit():  # 检查是否为有效的数字字符串
        page_size = int(page_size)
    else:
        page_size = 10  # 如果不是有效的数字，设置为默认值

    # 新建会话
    session = Session()

    # 总查询
    query = session.query(Document)

    if title:
        query = query.filter(Document.title.ilike(f'%{title}%'))  #模糊匹配
    if contributor:
        query = query.filter(Document.contributor.ilike(f'%{contributor}%'))


    # 总Worker数
    total = query.count()
    # 指定页码，页长
    files = query.offset((page_num - 1)*page_size).limit(page_size).all()

    # 关闭会话
    session.close()
    try:
        record = []
        for file in files:
            record.append({'id':file.id,
                           'filetitle':file.title,
                           'contributor':file.contributor,
                           'filedescription':file.description})

        data = {
            "record":record,
            'total':total
        }

        response_data = {
            "data":data,
            "code":0,
            "msg":"OK"
        }

        return jsonify(response_data),200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        # 注意：如果你使用的是SQLAlchemy的scoped_session或者自动会话管理，这步可能是不必要的
        session.close()


# 上传文件
@app.route('/pdfs', methods=['POST'])
@jwt_required()
def upload_file():
    if 'file' not in request.files:
        return jsonify({'code': 1, 'msg': '没有找到文件'}), 400

    file = request.files['file']
    description = request.form.get('filedescription')
    title = request.form.get('filetitle')
    contributor = request.form.get('contributor')

    if not contributor or not title or not description:
        return jsonify({'code': 1, 'msg': '缺少必要的表单字段'}), 400

    if file.filename == '':
        return jsonify({'code': 1, 'msg': '没有选择文件'}), 400
    if file.content_length > MAX_CONTENT_LENGTH:
        return jsonify({'code': 1, 'msg': '文件太大，不能超过10MB'}), 400

        # 清理文件名并准备保存
    # filename = secure_filename(file.filename)
    filename = file.filename
    filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)

    # 检查文件是否已存在，并修改文件名以避免冲突
    counter = 1
    while os.path.exists(filepath):
        # 尝试添加一个递增的后缀
        base, ext = os.path.splitext(filename)
        filename = f"{base}({counter}){ext}"
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        counter += 1

        # 保存文件
    file.save(filepath)

    # 数据库操作
    session = Session()
    try:
        new_file = Document(path=filename, contributor=contributor, description=description, title=title)
        session.add(new_file)
        session.commit()

        return jsonify({'code': 0, 'msg': '文件上传成功', 'filename': filename}), 200

    except Exception as e:
        session.rollback()
        return jsonify({"error": str(e)}), 500
    finally:
        session.close()

# 删除文件
@app.route('/pdfs/del',methods=['DELETE'])
@jwt_required()
def del_file():

    # 权限限制
    claims = get_jwt()
    power = claims.get('power')

    if power < 1:
        return jsonify({"code": 1, "msg": "权限不足"}), 403

    file_id = request.args.get('id')

    if not file_id:
        return jsonify({'code':1,'msg':'找不到文件'}),400

    file_id = int(file_id)
    session = Session()
    try:
        document = session.query(Document).filter_by(id=file_id).first()

        if not document:
            return jsonify({"code": 1, "msg": "找不到对应的文件"}), 404

        path = document.path
        # 提交更改
        session.delete(document)
        session.commit()

        # 从服务器上删除文件
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], path)
        if os.path.exists(filepath):
            os.remove(filepath)

        response_data = {
            "code":0,
            "msg":"删除成功"
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
    # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        session.close()

# 修改上传的文件
@app.route('/pdfs/edit',methods=['PUT'])
@jwt_required()
def alter_file():

    contributor = request.form.get('contributor')
    title = request.form.get('filetitle')
    description = request.form.get('filedescription')
    id = request.form.get('id')

    if not contributor:
        return jsonify({'code': 1, 'msg': '没有选择上传者'}), 400

    if not title:
        return jsonify({'code': 1, 'msg': '没有文档标题'}), 400

    if not description:
        return jsonify({'code': 1, 'msg': '没有文档描述'}), 400

    if not id:
        return jsonify({'code': 1, 'msg': '没有选择文件'}), 400

    # 权限限制
    identity = get_jwt_identity()

    session = Session()
    try:

        user = session.query(User).filter_by(username=identity).first()
        if not user or contributor != user.name:
            return jsonify({"code": 1, "msg": "权限不足"}), 403

        file = session.query(Document).filter_by(id=id).first()

        if not file:
            return jsonify({'code':1,'msg':'文件丢失'}),400

        if file.contributor != contributor:
            return jsonify({'code':1,'msg':'该文件不是由你上传的'}),400

        file.title = title
        file.description = description

        if 'file' in request.files:
            new_file = request.files['file']

            if new_file and new_file.content_length > MAX_CONTENT_LENGTH:
                return jsonify({'code': 1, 'msg': '文件太大，不能超过10MB'}), 400

            if new_file:
                filename = new_file.filename
                # 可以选择对文件名进行重命名或添加前缀/后缀以防止命名冲突
                # 例如: filename = secure_filename(file.filename)
                new_filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
                filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.path)
                # 确保文件不会覆盖已有文件（可选）
                if not os.path.exists(filepath):
                    return jsonify({'code': 1, 'msg': '原文件不存在'}), 400

                os.remove(filepath)
                new_file.save(new_filepath)
                file.path = new_file.filename

        session.commit()
        response_data = {
            "code":0,
            "msg":"修改成功"
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        session.close()

# 删除个人上传的文件
@app.route('/pdfs/stu/del',methods=['DELETE'])
@jwt_required()
def del_own_file():

    file_id = request.args.get('id')

    if not file_id:
        return jsonify({'code':1,'msg':'找不到文件'}),400

    # 权限
    identity = get_jwt_identity()

    file_id = int(file_id)
    session = Session()
    try:
        user = session.query(User).filter_by(username=identity).first()

        document = session.query(Document).filter_by(id=file_id).first()

        if not document:
            return jsonify({"code": 1, "msg": "找不到对应的文件"}), 404

        if not user or document.contributor != user.name:
            return jsonify({'code':1,'msg':'该文件不是由你上传的'}),403

        path = document.path
        # 提交更改
        session.delete(document)
        session.commit()

        # 从服务器上删除文件
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], path)
        if os.path.exists(filepath):
            os.remove(filepath)

        response_data = {
            "code":0,
            "msg":"删除成功"
        }
        # 返回成功消息
        return jsonify(response_data), 200

    except Exception as e:
        # 捕获并处理异常
        session.rollback()  # 如果有异常发生，回滚会话
        return jsonify({"error": str(e)}), 500
    finally:
        # 关闭会话（如果Session不是上下文管理的）
        session.close()

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=5000)
